/** 
 */

package com.vecspace.database.dao;

import org.hibernate.dialect.SQLServer2005Dialect;

import com.vecspace.data.model.IPagination;


/**SQL Server方言扩展类
 * 此类继承SQLServer2005Dialect实现，详情可参阅该类源码。
 * @类型名称 SQLServerDialectEx
 * @author
 */
public class SQLServerDialectEx extends SQLServer2005Dialect {
	/**
	 * <b>
	 * 	//重要说明！！！！此方法还不够完善！！！<p>
	 * 	//！！！注意：此方法仅解决了SQL Server下的分页，但未处理传入SQL中用别名排序的情况，如含有则会发生异常。<p>
	 * 	//重要说明！！！！此方法还不够完善！！！<p>
	 * </b> 
	 * 功能描述：获取分页语句，使用了sql server2005（含）以上版本的ROW_NUMBER()新特性，
	 * 故不支持2005以下版本的数据库。
	 * 生成的SQL语句格式如下：	 
	 * <pre>
	 * WITH query AS (
	 *   SELECT ROW_NUMBER() OVER (ORDER BY orderby) as __hibernate_row_nr__, 
	 *   original_query_without_orderby
	 * )
	 * SELECT * FROM query WHERE __hibernate_row_nr__ BEETWIN offset AND offset + last
	 * </pre>
	 * 
	 * @param page
	 * @param querySqlString
	 * @return 
	 * @author 
	 */
	public static String getLimitString(IPagination pagination, String querySqlString) {
		return getLimitString(pagination.getStartRows(), pagination.getEndRows(), querySqlString);
	}
	/**
	 * <b>
	 * 	//重要说明！！！！此方法还不够完善！！！<p>
	 * 	//！！！注意：此方法仅解决了SQL Server下的分页，但未处理传入SQL中用别名排序的情况，如含有则会发生异常。<p>
	 * 	//重要说明！！！！此方法还不够完善！！！<p>
	 * </b> 
	 * 功能描述：获取分页语句，使用了sql server2005（含）以上版本的ROW_NUMBER()新特性，
	 * 故不支持2005以下版本的数据库。
	 * 生成的SQL语句格式如下：	 
	 * <pre>
	 * WITH query AS (
	 *   SELECT ROW_NUMBER() OVER (ORDER BY orderby) as __hibernate_row_nr__, 
	 *   original_query_without_orderby
	 * )
	 * SELECT * FROM query WHERE __hibernate_row_nr__ BEETWIN offset AND offset + last
	 * </pre>
	 * 
	 * @param startrow
	 * @param endrow
	 * @param querySqlString
	 * @return 
	 * @author 
	 */
	public static String getLimitString(int startrow,int endrow,String querySqlString) {
		//重要说明！！！！此方法还不够完善！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
		//！！！注意：此方法仅解决了SQL Server下的分页，但未处理传入SQL中用别名排序的情况，如含有则会发生异常。
		//重要说明！！！！此方法还不够完善！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！！
		StringBuilder sb = new StringBuilder(querySqlString.trim().toLowerCase());

		int orderByIndex = sb.indexOf("order by");
		CharSequence orderby = orderByIndex > 0 ? sb.subSequence(orderByIndex, sb.length())
				: "ORDER BY CURRENT_TIMESTAMP";

		// Delete the order by clause at the end of the query
		if (orderByIndex > 0) {
			sb.delete(orderByIndex, orderByIndex + orderby.length());
		} 
		//如果传入的sql有多个form就可能有问题。。。。。
		int selectEndIndex = sb.indexOf(" from ");   
		sb.insert(selectEndIndex - 1, (new StringBuilder()).append(", ROW_NUMBER() OVER (").append(orderby).append(") as __hibernate_row_nr__ ").toString()); 
		// Wrap the query within a with statement:
		sb.insert(0, "WITH query AS (").append(") SELECT * FROM query ");
		sb.append("WHERE __hibernate_row_nr__ BETWEEN ").append(startrow).append(" AND ").append(endrow);

		return sb.toString();
	}
	
}
